package com.coolw.test.sftp.monitor;

import com.jcraft.jsch.SftpProgressMonitor;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.text.DecimalFormat;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 监控sftp传输
 *
 * @author coolw
 * @date 2023/11/17 10:54
 */
@Slf4j
public class TimeSftpProgressMonitor2 implements SftpProgressMonitor {

    ExecutorService executor = Executors.newSingleThreadExecutor();

    /**
     * 记录已传输的数据总大小
     */
    private long transfered;
    /**
     * 记录文件总大小
     */
    private long fileSize;
    /**
     * 记录传输是否结束
     */
    private boolean isEnd = false;

    public void monitor(long transfered) {
        double d = ((double) transfered * 100) / (double) fileSize;
        DecimalFormat df = new DecimalFormat("#.##");
        log.info("当前传输进度为 {}%, 已传输 {} bytes", df.format(d), transfered);
    }

    @Override
    public void init(int op, String src, String dest, long max) {
        File file = new File(src);
        this.fileSize = file.length();
        log.info("Transfer start=======================文件大小 {} bytes", fileSize);
    }

    @Override
    public boolean count(long count) {
        synchronized (this) {
            if (isEnd) {
                return false;
            }

            add(count);
            long currentTransfered = this.getTransfered();
            if (currentTransfered == fileSize) {
                setEnd(true);
            }
            executor.execute(() -> monitor(currentTransfered));
        }
        return true;
    }

    @Override
    public void end() {
        setEnd(true);
        log.info("Transfer end=======================已传输 {} bytes", getTransfered());
    }

    private synchronized void add(long count) {
        transfered = transfered + count;
    }

    private synchronized long getTransfered() {
        return this.transfered;
    }


    private synchronized void setEnd(boolean isEnd) {
        this.isEnd = isEnd;
    }

    private synchronized boolean isEnd() {
        return isEnd;
    }
}
